package cn.com.xy.sms.sdk.number;

import java.util.HashMap;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;

import cn.com.xy.sms.sdk.Iservice.XyCallBack;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.entity.NumberInfo;
import cn.com.xy.sms.sdk.db.entity.NumberInfoManager;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.service.number.UploadUserTagService;
import cn.com.xy.sms.sdk.util.CallBackState;
import cn.com.xy.sms.sdk.util.ThreadPoolManager;
import cn.com.xy.sms.sdk.util.XyUtil;

/* SDK-428 huangzhiqiang 20160618 start */
public class UserTagUtil {
    /**
     * 上传用户标记
     * 
     * @param num 号码
     * @param tag 用户标记内容
     * @param tagType 用户标记内容类型(1:系统预制类型 2:自定义类型)
     * @param extend 扩展参数
     * @param callBack 
     *            index0(状态，一般只需关注UPLOAD_COMPLETE状态):
     *                  CallBackState.UPLOAD_COMPLETE:新线程，上传完成
     *                  CallBackState.ERROR:当前线程或新线程，存在异常，上传失败 
     *            index1:num
     *            index2:
     *                  (index0 == CallBackState.UPLOAD_COMPLETE):上传完成时间
     *                  (index0 == CallBackState.ERROR):String类型 异常信息
     */
    public static void uploadUserTag(final String num, final String tag, final int tagType,
            final Map<String, String> extend, final XyCallBack callBack) {
        JSONObject numInfo = NumberInfoManager.saveUserTag(num, tag, tagType, extend);
        if (numInfo == null) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, num, "save user tag fail");
            return;
        }

        ParseNumberCache.addCache(num, numInfo);
        ParseNumberCache.removeInvalidNum(num);

        try {
            ThreadPoolManager.REPARSE_INVALID_NUM_DATA.execute(new Runnable() {

                @Override
                public void run() {
                    Map<String, String[]> uploadNumberMap = createUploadNumMap(num, tag, tagType);
                    UploadUserTagService.uploadToService(uploadNumberMap, extend, new XyCallBack() {

                        @Override
                        public void execute(Object... obj) {
                            try {
                                int callBackState = (Integer) obj[0];
                                Object result = obj[2];
                                if (callBackState != CallBackState.UPLOAD_COMPLETE) {
                                    XyUtil.doXycallBackResult(callBack, callBackState, num, result);
                                    return;
                                }

                                // 用户标记上传成功并且已更新数据库上传状态，更新缓存里的用户标记上传状态
                                if (updateUploadUserTagStatusSuccess(num, result)) {
                                    ParseNumberCache.updateUserTagUploadStatusCache(num,
                                            NumberInfo.UPLOAD_STATUS_UPLOADED);
                                }

                                XyUtil.doXycallBackResult(callBack, CallBackState.UPLOAD_COMPLETE, num,
                                        System.currentTimeMillis());
                            } catch (Throwable e) {
                                LogManager.e(Constant.TAG,
                                        "UploadUserTag uploadUserTag execute error:", e);
                                XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, num, e.getMessage());
                            }
                        }

                        private boolean updateUploadUserTagStatusSuccess(String num, Object result) {
                            return result != null && result instanceof JSONArray
                                    && ((JSONArray) result).optString(0).equals(num);
                        }
                    });
                }
            });
        } catch (Throwable e) {
            XyUtil.doXycallBackResult(callBack, CallBackState.ERROR, num, e.getMessage());
            LogManager.e(Constant.TAG, "UploadUserTag uploadUserTag error:", e);
        }
    }

    private static Map<String, String[]> createUploadNumMap(String num, String tag, int tagType) {
        Map<String, String[]> uploadNumberMap = new HashMap<String, String[]>();
        uploadNumberMap.put(num, new String[] { tag, String.valueOf(tagType) });
        return uploadNumberMap;
    }

    public static void removeUserTag(final String num, Map<String, String> extend) {
        NumberInfoManager.removeUserTag(num);
        ParseNumberCache.removeUserTag(num);
    }
}
/* SDK-428 huangzhiqiang 20160618 end */